package com.zzx.Tes;

import lombok.Getter;
import lombok.Setter;

import java.util.*;

/**
 * @Author: zzx
 * @Date: 2025/6/25 22:38
 */
public class Interview {

    /**
     * 评分策略接口 - 定义所有题型评分策略的通用方法
     * 所有具体评分策略类必须实现此接口。
     */
    interface ScoringStrategy {

        /**
         * 计算题目得分
         *
         * @param question 题目对象，包含题目信息和正确答案
         * @param userAnswers 用户提交的答案列表
         * @return 该题目的实际得分
         */
        double calculateScore(Question question, List<String> userAnswers);
    }

    /**
     * 单选题评分策略
     *
     * <p>评分规则：
     * 1. 只能有一个答案
     * 2. 答案必须完全正确才能得满分
     * 3. 多选、少选或不匹配都不得分</p>
     */
    class SingleChoiceScoring implements ScoringStrategy {

        /**
         * 计算单选题得分
         *
         * <p>实现细节：
         * - 检查用户答案数量，只能有1个答案
         * - 与题目的正确答案列表中的第一个答案比较
         * - 完全匹配得满分，否则0分</p>
         */
        @Override
        public double calculateScore(Question question, List<String> userAnswers) {
            // 用户答案数量验证
            if (userAnswers == null || userAnswers.size() != 1) {
                return 0.0; // 无答案或答案数量不为1不得分
            }

            // 获取题目的正确答案（单选题只有一个正确答案）
            String correctAnswer = question.getCorrectAnswers().get(0);

            // 答案比对
            return userAnswers.get(0).equals(correctAnswer) ? question.getMaxScore() : 0.0;
        }
    }

    /**
     * 多选题评分策略
     *
     * <p>评分规则：
     * 1. 用户选择了所有正确答案且没有错误答案得满分
     * 2. 部分答对按比例给分（如正确答案3个，答对2个得2/3分）
     * 3. 有任何错误选项不得分（0分）</p>
     */
    class MultipleChoiceScoring implements ScoringStrategy {

        /**
         * 计算多选题得分
         *
         * <p>实现细节：
         * - 检查每个用户答案是否都在正确答案集中
         * - 发现任何错误答案立即返回0分
         * - 全部答对按比例给分（针对部分答对的情况）</p>
         */
        @Override
        public double calculateScore(Question question, List<String> userAnswers) {
            if (userAnswers == null || userAnswers.isEmpty()) {
                return 0.0; // 未作答不得分
            }

            List<String> correctAnswers = question.getCorrectAnswers();
            Set<String> correctSet = new HashSet<>(correctAnswers);

            // 检查是否有错误答案
            for (String answer : userAnswers) {
                if (!correctSet.contains(answer)) {
                    return 0.0; // 有任何错误选项不得分
                }
            }

            // 计算部分得分（答对的选项数）
            double scorePerOption = question.getMaxScore() / correctAnswers.size();
            return userAnswers.size() * scorePerOption;
        }
    }

    /**
     * 完形填空评分策略
     *
     * <p>评分规则：
     * 1. 每个空独立计分
     * 2. 正确答案数 / 总空数 * 满分 = 实际得分
     * 3. 答案顺序必须完全匹配</p>
     */
    class ClozeScoring implements ScoringStrategy {

        /**
         * 计算完形填空题得分
         *
         * <p>实现细节：
         * - 验证用户答案数量与题目要求是否一致
         * - 逐空比对答案是否正确
         * - 按正确答案比例计算得分</p>
         */
        @Override
        public double calculateScore(Question question, List<String> userAnswers) {
            if (userAnswers == null) {
                return 0.0; // 未作答不得分
            }

            List<String> correctAnswers = question.getCorrectAnswers();

            // 答案数量验证
            if (userAnswers.size() != correctAnswers.size()) {
                return 0.0; // 答案数量不匹配，可能是未完整作答
            }

            // 统计正确答案数
            int correctCount = 0;
            for (int i = 0; i < userAnswers.size(); i++) {
                if (userAnswers.get(i).equals(correctAnswers.get(i))) {
                    correctCount++;
                }
            }

            // 按比例计算得分
            return question.getMaxScore() * (correctCount / correctAnswers.size());
        }
    }

    /**
     * 阅读理解评分策略
     *
     * <p>评分规则：
     * 1. 通常阅读理解有多个小题，但这里处理单个小题
     * 2. 每个小题按单选题处理</p>
     *
     * <p>说明：实际项目中可能需要不同的实现，
     * 这里仅作为示例展示可扩展性</p>
     */
    class ReadingScoring implements ScoringStrategy {

        /**
         * 计算阅读理解题得分
         *
         * <p>实现细节：
         * - 按单选题逻辑处理</p>
         */
        @Override
        public double calculateScore(Question question, List<String> userAnswers) {

            if (userAnswers == null || userAnswers.size() != 1) {
                return 0.0;
            }

            // 获取正确答案（取第一个）
            String correctAnswer = question.getCorrectAnswers().get(0);
            return userAnswers.get(0).equals(correctAnswer) ? question.getMaxScore() : 0.0;
        }
    }

    /**
     * 题目实体类 - 表示试卷中的单个题目
     *
     * <p>设计说明：
     * 2. 构造时根据题目类型自动设置评分策略
     * 3. 提供calculateScore()方法计算该题得分</p>
     */
    @Getter
    @Setter
    class Question {
        private String id;              // 题目唯一ID
        private String title;           // 题目内容
        private double maxScore;        // 该题满分
        private List<String> correctAnswers; // 正确答案列表
        private transient ScoringStrategy scoringStrategy; // 评分策略（不序列化）
        private String type;            // 题目类型

        public Question(String id, String title, double maxScore,
                        List<String> correctAnswers, String type) {
            this.id = id;
            this.title = title;
            this.maxScore = maxScore;
            this.correctAnswers = correctAnswers;
            this.type = type;
            setScoringStrategy(type);
        }

        /**
         * 根据题目类型设置评分策略
         *
         * @param type 题目类型标识
         */
        private void setScoringStrategy(String type) {
            switch (type.toLowerCase()) {
                case "single":      // 单选题
                case "singlechoice":
                    this.scoringStrategy = new SingleChoiceScoring();
                    break;
                case "multiple":    // 多选题
                case "multiplechoice":
                    this.scoringStrategy = new MultipleChoiceScoring();
                    break;
                case "cloze":       // 完形填空
                    this.scoringStrategy = new ClozeScoring();
                    break;
                case "reading":     // 阅读理解
                    this.scoringStrategy = new ReadingScoring();
                    break;
                default:
                    throw new IllegalArgumentException("不支持的题型: " + type);
            }
        }

        /**
         * 计算该题目得分
         *
         * @param userAnswers 用户提交的答案
         * @return 该题实际得分
         */
        public double calculateScore(List<String> userAnswers) {
            if (scoringStrategy == null) {
                throw new IllegalStateException("该题目未设置评分策略");
            }
            return scoringStrategy.calculateScore(this, userAnswers);
        }
    }


    class SectionDetail {
        private String id;//主键
        private String SectionId; //答题ID
        private String content;//题目内容
        private String questionId;//
    }

    /**
     * 大题实体类
     * <p>设计说明：
     * 1. 一个大题包含相同题型的多个小题
     * 2. 负责计算整个大题的得分</p>
     */

    @Getter
    @Setter
    class Section {
        private String id;              // 大题唯一ID
        private String title;           // 大题标题
        private String type;            // 大题题型
        private List<Question> questions; // 包含的小题列表

        public Section(String id, String title, String type, List<Question> questions) {
            this.id = id;
            this.title = title;
            this.type = type;
            this.questions = questions;
        }

        /**
         * 计算本大题得分
         *
         * @param answerSheet 答题卡对象，包含所有答题信息
         * @return 本大题实际得分
         */
        public double calculateScore(AnswerSheet answerSheet) {
            double sectionScore = 0.0;
            Map<String, List<String>> answers = answerSheet.getAnswers();

            for (Question question : questions) {
                // 获取该题的用户答案
                List<String> userAnswers = answers.get(question.getId());

                // 题目有答案才计算得分
                if (userAnswers != null) {
                    sectionScore += question.calculateScore(userAnswers);
                }
            }

            return sectionScore;
        }
    }

    /**
     * 答题卡类 - 表示学生提交的答卷
     *
     * <p>包含属性：
     * - id: 答题卡唯一标识
     * - studentId: 学生ID
     * - examDate: 考试日期
     * - answers: 答题情况映射（题目ID → 学生答案列表）</p>
     */
    @Getter
    @Setter
    class AnswerSheet {
        private String id;                  // 答题卡ID
        private String studentId;           // 学生学号
        private Date examDate;              // 考试日期
        private Map<String, List<String>> answers; // 答题情况（题目ID->答案列表）

        public AnswerSheet(String id, String studentId, Date examDate,
                           Map<String, List<String>> answers) {
            this.id = id;
            this.studentId = studentId;
            this.examDate = examDate;
            this.answers = answers;
        }
    }

    /**
     * 试卷类 - 表示一套完整的试卷
     *
     * <p>核心功能：
     * 计算整套试卷的总分</p>
     */
    @Getter
    @Setter
    class ExamPaper {
        private String id;              // 试卷ID
        private String title;           // 试卷标题
        private Date createDate;        // 创建日期
        private List<Section> sections; // 包含的大题列表

        public ExamPaper(String id, String title, Date createDate,
                         List<Section> sections) {
            this.id = id;
            this.title = title;
            this.createDate = createDate;
            this.sections = sections;
        }

        /**
         * 计算试卷总分
         *
         * @param answerSheet 学生答题卡
         * @return 试卷总得分
         */
        public double calculateTotalScore(AnswerSheet answerSheet) {
            double totalScore = 0.0;

            // 遍历所有大题，累加分数
            for (Section section : sections) {
                totalScore += section.calculateScore(answerSheet);
            }
            return totalScore;
        }
    }
}
